# -*- coding:utf8 -*-
import json
import traceback
import os
import re
import typing
import requests
from datetime import datetime
from scrapy import Request
from squirrel_core.commons.utils.tools import calc_str_md5, upload_file
from squirrel_core.frame.spider_makaka import MakakaSpider

file_path = os.environ.get("FILE_PATH", "/")


class diyisaidao_score(MakakaSpider):
    name = "diyisaidao_score"
    serialNumber = ""
    url = "https://matchapi.gusto.cn/api/user/card/create"
    unbind_url = "https://matchapi.gusto.cn/api/user/card/delete"
    header = {
        "Host": "matchapi.gusto.cn",
        "client-token": "15ae104746b40c2e74e9e31cf3529f38",
        "Content-Type": "application/json;charset=UTF-8"
    }

    def get_ext_requests_or_urls(self, data=None):
        if data and isinstance(data, str):
            data = json.loads(data)
        if data and isinstance(data, typing.MutableMapping):
            self.serialNumber = data.get("serialNumber", "")
            race_id = data.get("spider_config", {}).get("race_id", "")
            user_id = data.get("spider_config", {}).get("user_id", "")
            race_no = data.get("spider_config", {}).get("race_no", "")
            user_name = data.get("spider_config", {}).get("user_name", "")
            card_num = data.get("spider_config", {}).get("card_num", "")
            race_name = data.get("spider_config", {}).get("race_name", "").replace(" ", "")
            home_url = data.get("spider_config", {}).get("url", "")
            if not card_num:
                self.logger.info("card_num必须存在")
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 203, "message": "card_num必须存在"})
                self.close_after_idle = True
                self.force_to_close_spider = True
            else:
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 100, "message": "任务启动成功"})

                if int(card_num[-2:-1]) % 2 == 0:
                    sex = 2
                else:
                    sex = 1
                data = {"me": False, "realName": user_name, "pinyin": "ZHANG SAN", "sex": sex, "cardType": 1,
                        "cardNumber": card_num, "birthday": 846633600000, "country": "中国", "province": "北京市",
                        "city": "北京市", "area": "东城区", "address": "东大街234号", "mobile": "18721453548",
                        "email": "dasda@163.com", "size": "L", "emergencyContact": "李四",
                        "emergencyContactMobile": "18912357461", "bloodType": 1}

                yield Request(url=self.url, method="POST", callback=self.parse, body=json.dumps(data),
                              headers=self.header, dont_filter=True, errback=self.err_parse,
                              meta={"race_id": race_id, "user_id": user_id, "user_name": user_name,
                                    "race_name": race_name, "card_num": card_num, "race_no": race_no})

    def parse(self, response, **kwargs):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始绑定用户：{user_name}")
            code = json.loads(response.text).get("code", 0)
            if code in [200]:
                u_no = json.loads(response.text).get("data", "")
                url = "https://matchapi.gusto.cn/api/match/offline/list/my"
                yield Request(url=url, callback=self.parse_race_list, headers=self.header, dont_filter=True,
                              meta={"race_id": race_id, "user_id": user_id, "user_name": user_name,
                                    "race_name": race_name, "card_num": card_num, "race_no": race_no, "u_no": u_no})
            else:
                self.logger.info(f"绑定用户：{user_name}时出现问题：{json.loads(response.text)}")
                msg = json.loads(response.text).get("msg", "")
                result_data = {"msg": msg}
                result = self.result_item_assembler(response)
                result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                         "crawlerType": self.name_second, "data": str(result_data)}
                yield result
                current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                payload = {
                    "msgtype": "text",
                    "text": {
                        "content": f"【第一赛道：{current_time}】\n{msg}！",
                        "mentioned_list": ["@all"]
                    }
                }
                try:
                    wx_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=51e9de35-67d4-4d07-841d-fdeec8fbea3c"
                    requests.post(wx_url, headers={"Content-Type": "text/plain"}, data=json.dumps(payload), timeout=10)
                except Exception as e:
                    self.logger.error(f"代理异常监控信息发送失败, 原因: {e}")
                self.close_after_idle = True
                self.force_to_close_spider = True
        except Exception:
            self.logger.error(f"绑定用户：{user_name}时出错：{traceback.format_exc()}")

    def parse_race_list(self, response):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        u_no = response.meta.get("u_no", "")
        try:
            self.logger.info("开始解析赛事列表")
            n_list = json.loads(response.text).get("data", {}).get("notEndMatchList", [])
            e_list = json.loads(response.text).get("data", {}).get("endMatchList", [])
            n_list.extend(e_list)
            match_id = ""
            for match in n_list:
                match_name = match.get("matchTitle", "")
                if race_name in match_name and user_name == match.get("username", ""):
                    match_id = "".join(re.findall(r"\/(\d+)\?type=order", match.get("jumpContent", ""))).strip()
                    break
            if match_id:
                url = f"https://matchapi.gusto.cn/api/offline/template/cert?signId={match_id}"
                yield Request(url=url, callback=self.parse_score, headers=self.header, dont_filter=True,
                              meta={"race_id": race_id, "user_id": user_id, "user_name": user_name,
                                    "race_name": race_name, "race_no": race_no, "u_no": u_no})
            else:
                result_data = {"msg": "未查到成绩信息"}
                yield Request(url=self.unbind_url, method="POST", callback=self.parse_unbind, body=json.dumps({"cardId":u_no}),
                              headers=self.header, dont_filter=True, errback=self.err_parse,
                              meta={"name": user_name, "result_data": result_data, "user_id": user_id, "u_no": u_no})
        except Exception:
            self.logger.error(f"解析赛事列表时出错：{traceback.format_exc()}")

    def parse_score(self, response):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        u_no = response.meta.get("u_no", "")
        try:
            self.logger.info(f"获取{user_name}的成绩信息")
            data = json.loads(response.text).get("data", {})
            if data:
                score_data = {"origin_data": data}
                img_url = data.get("backgroundImage", "")
                if img_url:
                    yield Request(url=img_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"race_id": race_id, "user_name": user_name, "user_id": user_id,
                                        "score_data": score_data, "race_no": race_no, "u_no": u_no})
                else:
                    yield Request(url=self.unbind_url, method="POST", callback=self.parse_unbind,
                                  body=json.dumps({"cardId": u_no}),
                                  headers=self.header, dont_filter=True, errback=self.err_parse,
                                  meta={"name": user_name, "result_data": score_data, "user_id": user_id, "u_no": u_no})
            else:
                yield Request(url=self.unbind_url, method="POST", callback=self.parse_unbind,
                              body=json.dumps({"cardId": u_no}),
                              headers=self.header, dont_filter=True, errback=self.err_parse,
                              meta={"name": user_name, "result_data": {"msg": "未查到相关成绩信息"}, "user_id": user_id, "u_no": u_no})
        except Exception:
            self.logger.info(f"获取{user_name}的成绩信息错误：{traceback.format_exc()}")

    def parse_unbind(self, response):
        name = response.meta.get("name", "")
        u_no = response.meta.get("u_no", "")
        result_data = response.meta.get("result_data", {})
        try:
            self.logger.info(f"开始解绑{name},{u_no}")
            code = json.loads(response.text).get("code", 0)
            if code == 200:
                self.logger.info(f"解绑{name}成功,{u_no}")
            else:
                self.logger.info(f"解绑{name}失败,{u_no}")
            result = self.result_item_assembler(response)
            result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                     "crawlerType": self.name_second, "data": str(result_data)}
            yield result
        except Exception:
            self.logger.error(f"解绑{name}时出错：{traceback.format_exc()}")

    def parse_pic(self, response):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        u_no = response.meta.get("u_no", "")
        score_data = response.meta.get("score_data", {})
        try:
            self.logger.info(f"开始下载{user_name}的证书：{response.url}")
            pic_md5 = calc_str_md5(response.url)
            pic_name = f"{race_no}_{pic_md5}.jpg"
            dir_path = os.path.join(file_path, "picture", self.name_first)
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            save_path = os.path.join(dir_path, pic_name)
            if not os.path.exists(save_path):
                with open(save_path, "wb") as f:
                    f.write(response.body)
                upload_path = f"flow/{race_id}/{user_id}/pic/{pic_name}"
                upload_flag = upload_file(save_path, upload_path)
                if upload_flag:
                    self.logger.info(f"{save_path}上传成功：{upload_path}")
                else:
                    self.logger.info(f"{save_path}上传失败：{upload_path}")
                score_data["backgroundImage"] = upload_path
                yield Request(url=self.unbind_url, method="POST", callback=self.parse_unbind,
                              body=json.dumps({"cardId": u_no}),
                              headers=self.header, dont_filter=True, errback=self.err_parse,
                              meta={"name": user_name, "result_data": score_data, "user_id": user_id, "u_no": u_no})
        except Exception:
            self.logger.info(f"下载{user_name}证书时出错{response.url}：{traceback.format_exc()}")

    def err_parse(self, failure):
        self.logger.warning(f"请求失败：{failure.request.url},错误原因:{traceback.format_exc()}")

